package com.adcc.ags.msgStore.pool;

import com.adcc.ags.msgStore.DBConnectionFactory;
import com.adcc.ags.msgStore.common.Constant;
import com.adcc.utility.log.Log;
import com.google.common.base.Optional;
import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * C3P0数据库连接池
 */
public class C3P0Pool {

    private static ComboPooledDataSource cpds = null;

    private static Optional<DBConnectionFactory> dbConnectionFactoryOptional = null;

    /**
     * 初始化数据库连接池
     * @return
     */
    public static boolean init() {
        boolean flag = false;
        if(dbConnectionFactoryOptional.isPresent()){
            try {
                if (cpds == null) {
                    cpds = new ComboPooledDataSource();
                }
                cpds.setUser(dbConnectionFactoryOptional.get().getUsername());
                cpds.setPassword(dbConnectionFactoryOptional.get().getPassword());
                cpds.setJdbcUrl(dbConnectionFactoryOptional.get().getUrl());
                cpds.setDriverClass(dbConnectionFactoryOptional.get().getDriverClassName());
                cpds.setInitialPoolSize(dbConnectionFactoryOptional.get().getInitSize());
                cpds.setMaxIdleTime(dbConnectionFactoryOptional.get().getMaxIdleTime());
                cpds.setMaxPoolSize(dbConnectionFactoryOptional.get().getMaxSize());
                cpds.setMinPoolSize(dbConnectionFactoryOptional.get().getMinSize());
                cpds.setAcquireRetryAttempts(Constant.RETRYATTEMPTS);
                cpds.setUnreturnedConnectionTimeout(Constant.CONNECTIONTIMEOUT);
                cpds.setLoginTimeout(Constant.LOGINTIMEOUT);
                flag = true;
            } catch (Exception e) {
                Log.error(C3P0Pool.class.getName(),"Failed to init DB driver:", e);
            }
        }else{
            Log.error(C3P0Pool.class.getName(),"No initial configuration!");
        }
        return flag;
    }

    /**
     * 获取连接对象
     * @return   Connection
     */
    public static Optional<Connection> getConnection(){
        try {
            return Optional.of(cpds.getConnection());
        } catch (SQLException e) {
            Log.error(C3P0Pool.class.getName(),"get connection error",e);
            return Optional.absent();
        }
    }

    /**
     * 检测连接是否正常
     * @return
     */
    public static boolean checkConnection(){
        Connection connection = null;
        try {
            connection = cpds.getConnection();
            return true;
        } catch (SQLException e) {
            Log.error(C3P0Pool.class.getName(),"checkConnection error",e);
            return false;
        }finally {
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    Log.error(C3P0Pool.class.getName(),e);
                }
            }
        }
    }

    /**
     * 关闭连接
     * @param conn
     * @param pst
     * @param rs
     */
    public static void close(Connection conn, PreparedStatement pst, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                Log.error(C3P0Pool.class.getName(),e);
            }
        }
        if(pst!=null){
            try {
                pst.close();
            } catch (SQLException e) {
                Log.error(C3P0Pool.class.getName(),e);
            }
        }

        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                Log.error(C3P0Pool.class.getName(),e);
            }
        }
    }

    /**
     * 设置数据库连接池配置类
     * @param dbConnectionFactory
     */
    public static void setDbConnectionFactory(DBConnectionFactory dbConnectionFactory) {
        C3P0Pool.dbConnectionFactoryOptional = Optional.of(dbConnectionFactory);
    }
}
